package DEEPERsource.DEEPERsource.source.parser.stanfordparser.JUNGadapter;

import jung.entities.Graph;
import edu.stanford.nlp.trees.Tree;
import edu.uci.ics.jung.graph.DirectedEdge;
import edu.uci.ics.jung.graph.Vertex;
import edu.uci.ics.jung.graph.impl.DirectedSparseEdge;
import edu.uci.ics.jung.graph.impl.SparseVertex;
import edu.uci.ics.jung.utils.UserData;
import graph.Keys;

/**
 * Local builder isolates JUNG-specific graph building logic
 * 
 * @author tfayruzo
 *
 */
class ParseTreeBuilder implements Keys{
	private Graph parseTree;
	private int ind;
	private int innerInd;
	private int eInd;
	private Vertex parent;
			
	public void init(Tree root){
		ind = 1;
		innerInd = -1;
		eInd = 1;
		parent = null;
		parseTree = null;
		Vertex v = new SparseVertex();
		v.addUserDatum(LABEL, root.label().toString(), UserData.SHARED);		
		v.addUserDatum(INDEX, new Integer(innerInd), UserData.SHARED);
		parseTree = new Graph(v);
		setParent(innerInd);
	}
	
	public void setParent(int index){
		parent = parseTree.findVertex(index);
		if(parent == null)
			(new RuntimeException("Error constructing parse tree")).printStackTrace();			
	}
	
	public Graph getParseTree() {
		return parseTree;
	}
	
	public void addInnerEdge(int parent, Tree node){
		Vertex _node = new SparseVertex();
		_node.addUserDatum(LABEL, node.label().toString(), UserData.SHARED);
		_node.addUserDatum(INDEX, new Integer(--innerInd), UserData.SHARED);
		parseTree.addVertex(_node);
		DirectedEdge e = new DirectedSparseEdge(parseTree.findVertex(parent), _node);
		e.setUserDatum(INDEX, new Integer(eInd++), UserData.SHARED);
		parseTree.addEdge(e);
	}
	
	public void addLeafEdge(int parent, Tree node){
		Vertex _node = new SparseVertex();
		_node.addUserDatum(LABEL, node.label().toString(), UserData.SHARED);
		_node.addUserDatum(INDEX, new Integer(ind++), UserData.SHARED);
		parseTree.addVertex(_node);
		DirectedEdge e = new DirectedSparseEdge(parseTree.findVertex(parent), _node);
		e.setUserDatum(INDEX, new Integer(eInd++), UserData.SHARED);
		parseTree.addEdge(e);
	}
	
	public void addInnerVertex(Tree node, int i){
		Vertex _node = new SparseVertex();
		_node.addUserDatum(LABEL, node.label().toString(), UserData.SHARED);
		_node.addUserDatum(INDEX, new Integer(i), UserData.SHARED);
		parseTree.addVertex(_node);
		DirectedEdge e = new DirectedSparseEdge(parent, _node);
		e.setUserDatum(INDEX, new Integer(eInd++), UserData.SHARED);
		parseTree.addEdge(e);
	}
	
	public void addLeaf(Tree leaf){
		Vertex _leaf = new SparseVertex();
		_leaf.addUserDatum(LABEL, leaf.label().toString(), UserData.SHARED);
		_leaf.addUserDatum(INDEX, ind++, UserData.SHARED);
		parseTree.addVertex(_leaf);
		DirectedEdge e = new DirectedSparseEdge(parent, _leaf);
		e.setUserDatum(INDEX, new Integer(eInd++), UserData.SHARED);
		parseTree.addEdge(e);
	}
	
	public int getInternalId(){
		return innerInd;
	}
}
